package com.bestcem.xm.user.grpc.service.converter;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.bestcem.bp.grpc.v1.base.Page;
import com.bestcem.bp.xm.user.grpc.v1.services.GroupNode;
import com.bestcem.bp.xm.user.grpc.v1.services.*;
import com.bestcem.xm.user.enums.BooleanStatusEnum;
import com.bestcem.xm.user.grpc.service.param.*;
import com.bestcem.xm.user.grpc.v1.enums.GroupStatusEnum;
import com.bestcem.xm.user.grpc.v1.enums.GroupTypeEnum;
import com.bestcem.xm.user.service.dto.group.*;
import com.google.protobuf.ProtocolStringList;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * grpc请求出入参转化类
 *
 * @author Linked <zhijian.lin@idiaoyan.com>
 * @version v1.0
 * @date 2022/1/21 14:17
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class UserGroupConverter {

    /**
     * 将本地处理结果转换成grpc请求响应参数：获取门店id和名称的对应关系
     *
     * @param dtoList
     * @return java.util.List<com.bestcem.bp.xm.user.grpc.v1.services.StoreIdName>
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/1/21 16:46
     */
    public static List<StoreIdName> userDtoToStoreIdName(List<UserGroupDTO> dtoList) {
        List<StoreIdName> grpcList = new ArrayList<>();
        if (CollectionUtils.isEmpty(dtoList)) {
            return grpcList;
        }
        for (UserGroupDTO dto : dtoList) {
            StoreIdName.Builder builder = StoreIdName.newBuilder();
            if (StringUtils.isNotBlank(dto.getGroupId())) {
                builder.setId(dto.getGroupId());
            }
            if (StringUtils.isNotBlank(dto.getGroupName())) {
                builder.setName(dto.getGroupName());
            }
            if (StringUtils.isNotBlank(dto.getGroupCode())) {
                builder.setCode(dto.getGroupCode());
            }
            grpcList.add(builder.build());
        }
        return grpcList;
    }

    /**
     * 将层级信息列表转成grpc响应结果
     *
     * @param dtos 层级信息列表
     * @return java.util.List<com.bestcem.bp.xm.user.grpc.v1.services.GroupLevel>
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/01/24 11:47
     */
    public static List<GroupLevel> userGroupLevelDtosToGroupLevels(List<UserGroupLevelDTO> dtos) {
        List<GroupLevel> grpcList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(dtos)) {
            dtos.stream().forEach(d -> {
                GroupLevel.Builder groupLevelBuilder = GroupLevel.newBuilder();
                if (StringUtils.isNotBlank(d.getGroupLevelId())) {
                    groupLevelBuilder.setId(d.getGroupLevelId());
                }
                if (StringUtils.isNotBlank(d.getOrgId())) {
                    groupLevelBuilder.setOrgId(d.getOrgId());
                }
                if (StringUtils.isNotBlank(d.getGroupLevelName())) {
                    groupLevelBuilder.setName(d.getGroupLevelName());
                }
                if (Objects.nonNull(d.getLevelNum())) {
                    groupLevelBuilder.setLevel(d.getLevelNum());
                }
                groupLevelBuilder.setDisplay(StringUtils.isEmpty(d.getLevelDisplay()) ? "" : d.getLevelDisplay());
                if (StringUtils.isNotEmpty(d.getLevelChildrenId())) {
                    groupLevelBuilder.setChildrenId(d.getLevelChildrenId());
                }
                grpcList.add(groupLevelBuilder.build());
            });
        }
        return grpcList;
    }

    /**
     * grpc请求入参转换成本地入参
     *
     * @return com.bestcem.xm.user.group.grpc.service.param.GroupIdsPageParam
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/1/25 15:53
     */
    public static GroupIdsPageParam requestToGroupIdsPageParam(Page page, ProtocolStringList groupIdsList, boolean includeSub) {
        GroupIdsPageParam param = new GroupIdsPageParam();
        // 设置分页参数
        if (Objects.nonNull(page)) {
            param.setPageParam(new PageParam(page.getPage(), page.getSize()));
        }

        param.setGroupIds(groupIdsList).setIncludeSub(includeSub);
        return param;
    }

    /**
     * grpc请求入参转换成本地入参
     *
     * @param request
     * @return com.bestcem.xm.user.group.grpc.service.param.OrgStatusPageParam
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/2/7 15:42
     */
    public static OrgStatusPageParam requestToOrgStatsQueryParam(ListGroupsByOrgIdOrParentIdRequest request) {

        OrgStatusPageParam param = new OrgStatusPageParam();

        if (StringUtils.isNotBlank(request.getOrgId())) {
            param.setOrgId(request.getOrgId());
        }
        if (StringUtils.isNotBlank(request.getParentGroupId())) {
            param.setParentGroupId(request.getParentGroupId());
        }

        //设置状态
        List<Integer> statusList = new ArrayList<>();
        for (GroupStatusEnum.GroupStatus status : request.getStatusesList()) {
            statusList.add(status.getNumber());
        }
        param.setStatusList(statusList);

        //设置分页
        param.setPageParam(new PageParam(request.getPage().getPage(), request.getPage().getSize()));

        return param;
    }


    /**
     * 将用户组信息转成grpc响应结果
     *
     * @param dto 用户组信息
     * @return Group.Builder
     * @author yanjishuo <jishuo.yan@idiaoyan.cn>
     * @date 2022/01/24 15:00
     */
    public static Group userGroupDtoToGroup(UserGroupDTO dto) {
        Group.Builder group = Group.newBuilder();
        if (Objects.isNull(dto)) {
            return group.build();
        }
        if (StringUtils.isNotBlank(dto.getGroupId())) {
            group.setId(dto.getGroupId());
        }
        if (StringUtils.isNotBlank(dto.getOrgId())) {
            group.setOrgId(dto.getOrgId());
        }

        if (StringUtils.isNotBlank(dto.getGroupCode())) {
            group.setCode(dto.getGroupCode());
        }
        if (Objects.nonNull(dto.getSeq())) {
            group.setSeq(dto.getSeq());
        }
        if (StringUtils.isNotBlank(dto.getGroupName())) {
            group.setName(dto.getGroupName());
        }
        if (Objects.nonNull(dto.getGroupType())) {
            group.setTypeValue(dto.getGroupType());
        }
        if (StringUtils.isNotBlank(dto.getGroupLevelId())) {
            group.setLevelId(dto.getGroupLevelId());
        }
        if (Objects.nonNull(dto.getGroupStatus())) {
            group.setStatusValue(dto.getGroupStatus());
        }
        if (StringUtils.isNotBlank(dto.getGroupParentId())) {
            group.setParentId(dto.getGroupParentId());
        }
        if (StringUtils.isNotBlank(dto.getPhone())) {
            group.setPhone(dto.getPhone());
        }
        if (StringUtils.isNotBlank(dto.getEmail())) {
            group.setEmail(dto.getEmail());
        }
        if (StringUtils.isNotBlank(dto.getAdminId())) {
            group.setAdminId(dto.getAdminId());
        }
        if (StringUtils.isNotBlank(dto.getAdminName())) {
            group.setAdminName(dto.getAdminName());
        }
        String groupParentIds = dto.getGroupParentIds();
        List<String> parentIds = new ArrayList<>();
        // json格式转换成列表格式
        if (StringUtils.isNotEmpty(groupParentIds) && JSONUtil.isJsonArray(groupParentIds)) {
            parentIds = JSONUtil.toList(JSONUtil.parseArray(groupParentIds), String.class);
            // 获取第一个元素
            if (!CollectionUtils.isEmpty(parentIds)) {
                group.setRootId(parentIds.get(0));
                group.addAllParentIds(parentIds);
            }
        }
        group.setRoot(!CollectionUtils.isEmpty(parentIds));
        group.setHaveChildren(BooleanStatusEnum.toBoolean(dto.getHaveChildrenFlag()));
        return group.build();
    }

    /**
     * 将基本用户组信息列表转成grpc响应结果
     *
     * @param dtos 用户组信息
     * @return List<GroupBase>
     * @author yanjishuo <jishuo.yan@idiaoyan.cn>
     * @date 2022/01/24 16:00
     */
    public static List<GroupBase> userGroupDtosTobaseGroups(List<UserGroupDTO> dtos) {
        List<GroupBase> groupBaseList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(dtos)) {
            dtos.stream().forEach(d -> {
                GroupBase.Builder groupBase = GroupBase.newBuilder();
                if (StringUtils.isNotBlank(d.getGroupId())) {
                    groupBase.setId(d.getGroupId());
                }
                if (Objects.nonNull(d.getSeq())) {
                    groupBase.setSeq(d.getSeq());
                }
                if (StringUtils.isNotBlank(d.getGroupCode())) {
                    groupBase.setCode(d.getGroupCode());
                }
                if (StringUtils.isNotBlank(d.getGroupName())) {
                    groupBase.setName(d.getGroupName());
                }

                groupBaseList.add(groupBase.build());
            });
        }
        return groupBaseList;
    }

    /**
     * grpc请求入参转换成本地入参
     *
     * @param userRelateGroup 用户组信息
     * @return userUserGroupDTO
     * @author yanjishuo <jishuo.yan@idiaoyan.cn>
     * @date 2022/01/25 14:30
     */
    public static UserUserGroupDTO userRelateGroupToUserUserGroupDto(UserRelateGroup userRelateGroup) {
        UserUserGroupDTO userUserGroupDTO = new UserUserGroupDTO();
        if (!ObjectUtils.isEmpty(userRelateGroup)) {
            userUserGroupDTO.setUserGroupId(userRelateGroup.getId());
            userUserGroupDTO.setGroupId(userRelateGroup.getGroupId());
            userUserGroupDTO.setUserId(userRelateGroup.getUserId());
            userUserGroupDTO.setRootGroupId(userRelateGroup.getRootGroupId());
        }
        return userUserGroupDTO;
    }

    /**
     * 将基本用户组信息列表转成grpc响应结果
     *
     * @param dtos 用户组信息
     * @return List<GroupBase>
     * @author yanjishuo <jishuo.yan@idiaoyan.cn>
     * @date 2022/01/25 14:30
     */
    public static List<UserRelateGroup> userGroupDtosToUserRelateGroups(List<UserUserGroupDTO> dtos) {
        List<UserRelateGroup> userGroupList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(dtos)) {
            dtos.stream().forEach(d -> {
                UserRelateGroup.Builder userGroup = UserRelateGroup.newBuilder();
                if (StringUtils.isNotBlank(d.getUserGroupId())) {
                    userGroup.setId(d.getUserGroupId());
                }
                if (StringUtils.isNotBlank(d.getRootGroupId())) {
                    userGroup.setRootGroupId(d.getRootGroupId());
                }
                if (StringUtils.isNotBlank(d.getUserId())) {
                    userGroup.setUserId(d.getUserId());
                }
                if (StringUtils.isNotBlank(d.getGroupId())) {
                    userGroup.setGroupId(d.getGroupId());
                }
                userGroupList.add(userGroup.build());
            });
        }
        return userGroupList;
    }


    /**
     * GRPC参数类型转换
     *
     * @param request
     * @return UserGroupListParam
     * @author Linked <zhijian.lin@idiaoyan.com>
     * @date 2022/1/24 15:34
     */
    public static UserGroupListParam requestToUserGroupListParam(ListGroupsRequest request) {
        Page page = request.getPage();
        UserGroupListParam param = new UserGroupListParam();
        param.setPageParam(new PageParam(page.getPage(), page.getSize()));

        List<Integer> statusList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(request.getStatusesList())) {
            for (GroupStatusEnum.GroupStatus status : request.getStatusesList()) {
                statusList.add(status.getNumber());
            }
        }
        param.setStatuses(statusList);
        GroupCondition group = request.getGroup();
        param.setGroupId(group.getId());
        param.setGroupName(group.getName());
        param.setGroupCode(group.getCode());
        param.setGroupParentId(group.getParentId());
        if (group.hasStatus()) {
            param.setGroupStatus(group.getStatus().getNumber());
        }
        if (group.hasType()) {
            param.setGroupType(group.getTypeValue());
        }
        param.setOrgId(group.getOrgId());
        param.setGroupLevelId(group.getLevelId());
        param.setAdminId(group.getAdminId());
        return param;
    }

    /**
     * GRPC参数类型转换
     *
     * @param request
     * @return UserGroupListParam
     * @author Linked <zhijian.lin@idiaoyan.com>
     * @date 2022/1/24 15:34
     */
    public static SearchGroupsParam requestToSearchGroupsParam(SearchGroupsRequest request) {
        Page page = request.getPage();
        SearchGroupsParam param = new SearchGroupsParam();
        param.setPageParam(new PageParam(page.getPage(), page.getSize()));

        List<String> levelIdList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(request.getLevelIdsList())) {
            for (String levelId : request.getLevelIdsList()) {
                levelIdList.add(levelId);
            }
        }
        param.setLevelIdList(levelIdList);
        GroupCondition group = request.getGroup();
        param.setGroupId(group.getId());
        param.setGroupName(group.getName());
        param.setGroupCode(group.getCode());
        param.setGroupParentId(group.getParentId());
        param.setGroupType(group.getTypeValue());
        if (group.hasStatus()) {
            param.setGroupStatus(group.getStatus().getNumber());
        }
        if (group.hasType()) {
            param.setGroupType(group.getTypeValue());
        }
        param.setSeq(group.getSeq());
        param.setOrgId(group.getOrgId());
        param.setGroupLevelId(group.getLevelId());
        param.setAdminId(group.getAdminId());
        param.setSearch(request.getSearch());
        return param;
    }

    public static List<Group> userGroupDTOToResponse(List<UserGroupDTO> userGroup) {
        List<Group> groupList = new ArrayList<>();
        for (UserGroupDTO group : userGroup) {
            Group.Builder builder = Group.newBuilder();
            if (StringUtils.isNotBlank(group.getGroupId())) {
                builder.setId(group.getGroupId());
            }
            if (StringUtils.isNotBlank(group.getGroupCode())) {
                builder.setCode(group.getGroupCode());
            }
            if (StringUtils.isNotBlank(group.getGroupName())) {
                builder.setName(group.getGroupName());
            }
            if (Objects.nonNull(group.getGroupStatus())) {
                builder.setStatus(GroupStatusEnum.GroupStatus.forNumber(group.getGroupStatus()));
            }
            if (StringUtils.isNotBlank(group.getGroupParentId())) {
                builder.setParentId(group.getGroupParentId());
            }
            if (StringUtils.isNotBlank(group.getGroupParentIds())) {
                JSONArray array = JSON.parseArray(group.getGroupParentIds());
                if (!CollectionUtils.isEmpty(array)) {
                    builder.setRootId(array.get(0).toString());
                    builder.addAllParentIds(array.toJavaList(String.class));
                }
            }
            builder.setRoot(StringUtils.isEmpty(group.getGroupParentId()));
            if (StringUtils.isNotBlank(group.getOrgId())) {
                builder.setOrgId(group.getOrgId());
            }
            if (Objects.nonNull(group.getGroupType())) {
                builder.setType(GroupTypeEnum.GroupType.forNumber(group.getGroupType()));
            }
            if (Objects.nonNull(group.getSeq())) {
                builder.setSeq(group.getSeq());
            }
            if (StringUtils.isNotBlank(group.getGroupLevelId())) {
                builder.setLevelId(group.getGroupLevelId());
            }
            if (StringUtils.isNotBlank(group.getAdminId())) {
                builder.setAdminId(group.getAdminId());
            }
            builder.setHaveChildren(BooleanStatusEnum.toBoolean(group.getHaveChildrenFlag()));
            groupList.add(builder.build());
        }
        return groupList;
    }


    public static ListRelateGroupsParam requestToListRelateGroupsParam(ListRelatedGroupsRequest request) {
        ListRelateGroupsParam param = new ListRelateGroupsParam();
        param.setGroupIds(request.getGroupIdsList());
        param.setGroupLevelId(request.getGroupLevelId());
        PageParam pageParam = new PageParam(request.getPage().getPage(), request.getPage().getSize());
        param.setPageParam(pageParam);
        return param;
    }

    public static List<GroupBase> userGroupBaseToResponse(List<GroupBaseDTO> baseGroupList) {
        List<GroupBase> groupBaseList = new ArrayList<>();
        for (GroupBaseDTO baseDTO : baseGroupList) {
            GroupBase.Builder builder = GroupBase.newBuilder();
            if (StringUtils.isNotBlank(baseDTO.getId())) {
                builder.setId(baseDTO.getId());
            }
            if (StringUtils.isNotBlank(baseDTO.getCode())) {
                builder.setCode(baseDTO.getCode());
            }
            if (Objects.nonNull(baseDTO.getSeq())) {
                builder.setSeq(baseDTO.getSeq());
            }
            if (StringUtils.isNotBlank(baseDTO.getName())) {
                builder.setName(baseDTO.getName());
            }
            groupBaseList.add(builder.build());
        }
        return groupBaseList;
    }

    public static SyncUserGroupRelateParam userGroupRelateToRequest(SyncUserRelatedGroupRequest request) {
        SyncUserGroupRelateParam param = new SyncUserGroupRelateParam();
        param.setGroupCodes(request.getGroupCodesList());
        param.setUserId(request.getUserId());
        param.setOrgId(request.getOrgId());
        return param;
    }

    public static ListSubGroupsByGroupIdsParam requestToListSubGroupsByGroupIdsParam(ListSubGroupsByGroupIdsRequest request) {
        ListSubGroupsByGroupIdsParam param = new ListSubGroupsByGroupIdsParam();
        PageParam pageParam = new PageParam(request.getPage().getPage(), request.getPage().getSize());
        param.setPageParam(pageParam);
        param.setGroupIds(request.getGroupIdsList());
        return param;
    }

    public static List<GroupBase> groupBaseDTOToGroupBase(List<GroupBaseDTO> groups) {
        List<GroupBase> groupList = new ArrayList<>();
        for (GroupBaseDTO base : groups) {
            GroupBase.Builder builder = GroupBase.newBuilder();
            if (StringUtils.isNotBlank(base.getName())) {
                builder.setName(base.getName());
            }
            if (Objects.nonNull(base.getSeq())) {
                builder.setSeq(base.getSeq());
            }
            if (StringUtils.isNotBlank(base.getId())) {
                builder.setId(base.getId());
            }
            if (StringUtils.isNotBlank(base.getCode())) {
                builder.setCode(base.getCode());
            }
            groupList.add(builder.build());
        }
        return groupList;
    }


    public static GetGroupsByOrgIdOrPage requestToGetGroupsByOrgIdOrPage(ListGroupsByOrgIdRequest request) {
        GetGroupsByOrgIdOrPage page = new GetGroupsByOrgIdOrPage();
        PageParam param = new PageParam(request.getPage().getPage(), request.getPage().getSize());
        page.setPageParam(param);
        page.setOrgId(request.getOrgId());
        page.setPageFlag(request.getPaging());
        return page;
    }

    /**
     * 将本地处理结果转换成grpc请求响应参数：API获取某个租户下的租住信息
     *
     * @param dtos
     * @return com.bestcem.bp.xm.user.grpc.v1.services.ApiGroupLevelInfo
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/02/17 17:48
     */
    public static List<OpenGroup> dtosToOpenGroupInfo(List<UserGroupDTO> dtos) {
        List<OpenGroup> grpcList = new ArrayList<>();
        for (UserGroupDTO dto : dtos) {
            OpenGroup.Builder builder = OpenGroup.newBuilder();
            if (StringUtils.isNotBlank(dto.getGroupId())) {
                builder.setId(dto.getGroupId());
            }
            if (StringUtils.isNotBlank(dto.getGroupCode())) {
                builder.setCode(dto.getGroupCode());
            }
            if (StringUtils.isNotBlank(dto.getGroupName())) {
                builder.setName(dto.getGroupName());
            }
            grpcList.add(builder.build());
        }
        return grpcList;
    }

    public static UserGroupListByUserIdParam requestToGroupListByUserId(ListGroupsByUidRequest request) {
        UserGroupListByUserIdParam param = new UserGroupListByUserIdParam();
        param.setPageParam(new PageParam(request.getPage().getPage(), request.getPage().getSize()));
        param.setUserId(request.getUserId());
        param.setFilterStatusFlag(request.getActivated());
        param.setIncludeChildFlag(request.getIncludeChildren());
        return param;
    }

    /**
     * 将用户组信息列表装成组织节点树
     *
     * @param groupDTOS   用户组信息列表
     * @param rootGroupId 跟节点id
     * @return com.bestcem.bp.xm.user.grpc.v1.services.GroupNode
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/04/07 20:42
     */
    public static GroupNode groupDtoToGroupNodeTree(List<UserGroupDTO> groupDTOS, String rootGroupId) {
        if (CollectionUtils.isEmpty(groupDTOS)) {
            return null;
        }
        // 按照groupParentId分组
        Map<String, List<GroupNode>> parentIdMap = groupDTOS.stream()
                .collect(Collectors.toMap(UserGroupDTO::getGroupParentId, u -> {
                    GroupNode.Builder builder = dtoToNode(u);
                    List<GroupNode> list = new ArrayList<>();
                    list.add(builder.build());
                    return list;
                }, (u1, u2) -> {
                    u1.addAll(u2);
                    return u1;
                }));
        // 得到第一个节点
        GroupNode root = groupDTOS.stream().map(u -> dtoToNode(u).build())
                .filter(u -> u.getId().equalsIgnoreCase(rootGroupId)).findFirst().orElse(null);

        if (Objects.isNull(root)) {
            return null;
        }

        String id = root.getId();
        if (StringUtils.isNotBlank(id)) {
            List<GroupNode> childrens = handleChildrens(parentIdMap.get(id), parentIdMap);
            root = root.toBuilder().addAllChildren(childrens).build();
        }

        return root;
    }

    private static List<GroupNode> handleChildrens(List<GroupNode> groupNodes, Map<String, List<GroupNode>> map) {
        List<GroupNode> result = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(groupNodes)) {
            for (GroupNode groupNode : groupNodes) {
                String id = groupNode.getId();
                if (map.containsKey(id)) {
                    List<GroupNode> groupNodeTemps = handleChildrens(map.get(id), map);
                    groupNode = groupNode.toBuilder().addAllChildren(groupNodeTemps).build();
                }
                result.add(groupNode);
            }
        }
        return result;
    }

    private static GroupNode.Builder dtoToNode(UserGroupDTO userGroupDTO) {
        GroupNode.Builder builder = GroupNode.newBuilder();
        if (StringUtils.isNotBlank(userGroupDTO.getGroupId())) {
            builder.setId(userGroupDTO.getGroupId());
        }
        if (Objects.nonNull(userGroupDTO.getSeq())) {
            builder.setSeq(userGroupDTO.getSeq());
        }
        if (StringUtils.isNotBlank(userGroupDTO.getGroupCode())) {
            builder.setCode(userGroupDTO.getGroupCode());
        }
        if (StringUtils.isNotBlank(userGroupDTO.getGroupName())) {
            builder.setName(userGroupDTO.getGroupName());
        }
        if (StringUtils.isNotBlank(userGroupDTO.getGroupLevelId())) {
            builder.setLevelId(userGroupDTO.getGroupLevelId());
        }
        return builder;
    }


    public static List<GroupNode> dtoToGroupNodeTree(List<GroupNodeDTO> nodeDTOList) {
        if (!CollectionUtils.isEmpty(nodeDTOList)) {
            List<GroupNode> groupNodes = new ArrayList<>();
            for (GroupNodeDTO node : nodeDTOList) {
                GroupNode.Builder builder = GroupNode.newBuilder();
                if (StringUtils.isNotBlank(node.getId())) {
                    builder.setId(node.getId());
                }
                if (StringUtils.isNotBlank(node.getGroupLevelId())) {
                    builder.setLevelId(node.getGroupLevelId());
                }
                if (StringUtils.isNotBlank(node.getCode())) {
                    builder.setCode(node.getCode());
                }
                if (Objects.nonNull(node.getSeq())) {
                    builder.setSeq(node.getSeq());
                }
                if (StringUtils.isNotBlank(node.getName())) {
                    builder.setName(node.getName());
                }
                if (!CollectionUtils.isEmpty(node.getChildren())) {
                    List<GroupNode> nodeList = dtoToGroupNodeTree(node.getChildren());
                    if (!CollectionUtils.isEmpty(nodeList)) {
                        builder.addAllChildren(nodeList);
                    }
                }
                groupNodes.add(builder.build());
            }
            return groupNodes;
        }
        return new ArrayList<>();
    }

    public static List<GroupBase> userGroupDtosToGroupBases(List<UserGroupDTO> rows) {
        List<GroupBase> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(rows)) {
            return result;
        }

        for (UserGroupDTO row : rows) {
            GroupBase.Builder builder = GroupBase.newBuilder();
            builder.setId(row.getGroupId());
            if (Objects.nonNull(row.getSeq())) {
                builder.setSeq(row.getSeq());
            }
            if (StringUtils.isNotEmpty(row.getGroupCode())) {
                builder.setCode(row.getGroupCode());
            }
            if (StringUtils.isNotEmpty(row.getGroupName())) {
                builder.setName(row.getGroupName());
            }
            result.add(builder.build());
        }

        return result;
    }

    public static OpenGroupTreeByAsyncParam openGroupTreeByAsyncGrpc2Dto(UpdateOpenGroupTreeByAsyncRequest request) {
        if ( request == null ) {
            return null;
        }
        OpenGroupTreeByAsyncParam openGroupTreeByAsyncParam = new OpenGroupTreeByAsyncParam();
        openGroupTreeByAsyncParam.setOrgId( request.getOrgId() );
        openGroupTreeByAsyncParam.setGroupFilePath( request.getFilePath() );
        openGroupTreeByAsyncParam.setGroupTotal( request.getTotal() );
        openGroupTreeByAsyncParam.setCallbackParam( request.getCallbackParam() );
        return openGroupTreeByAsyncParam;
    }

    private static GroupLevelSyncParam groupLevelSyncToGroupLevelSyncParam(GroupLevelSync groupLevelSync) {
        if ( groupLevelSync == null ) {
            return null;
        }

        GroupLevelSyncParam groupLevelSyncParam = new GroupLevelSyncParam();

        if ( groupLevelSync.getName() != null ) {
            groupLevelSyncParam.setName( groupLevelSync.getName() );
        }
        groupLevelSyncParam.setLevel( groupLevelSync.getLevel() );

        return groupLevelSyncParam;
    }

    private static GroupLevelSyncParam groupLevelSyncToGroupLevelSyncParamV1(GroupLevelSyncV1 groupLevelSync) {
        if ( groupLevelSync == null ) {
            return null;
        }

        GroupLevelSyncParam groupLevelSyncParam = new GroupLevelSyncParam();

        if ( groupLevelSync.getName() != null ) {
            groupLevelSyncParam.setName( groupLevelSync.getName() );
        }
        groupLevelSyncParam.setLevel( groupLevelSync.getLevel() );

        return groupLevelSyncParam;
    }

    public static List<GroupLevelSyncParam> grpcsToSyncLevels(List<GroupLevelSync> grpcs) {
        if ( grpcs == null ) {
            return Collections.emptyList();
        }

        List<GroupLevelSyncParam> list = new ArrayList<>( grpcs.size() );
        for ( GroupLevelSync groupLevelSync : grpcs ) {
            list.add( groupLevelSyncToGroupLevelSyncParam( groupLevelSync ) );
        }

        return list;
    }

    public static List<GroupLevelSyncParam> grpcsToSyncLevelsV1(List<GroupLevelSyncV1> grpcs) {
        if ( grpcs == null ) {
            return Collections.emptyList();
        }

        List<GroupLevelSyncParam> list = new ArrayList<>( grpcs.size() );
        for ( GroupLevelSyncV1 groupLevelSyncV1 : grpcs ) {
            list.add( groupLevelSyncToGroupLevelSyncParamV1( groupLevelSyncV1 ) );
        }

        return list;
    }

    private static GroupSyncParam groupSyncToGroupSyncParam(GroupSync groupSync) {
        if ( groupSync == null ) {
            return null;
        }

        GroupSyncParam groupSyncParam = new GroupSyncParam();
        groupSyncParam.setCode( groupSync.getCode() );
        groupSyncParam.setName( groupSync.getName() );
        groupSyncParam.setLevelName( groupSync.getLevelName() );
        groupSyncParam.setParentCode( groupSync.getParentCode() );
        groupSyncParam.setRootFlag( groupSync.getRoot() );
        if (StringUtils.isNotBlank(groupSync.getAdminName())) {
            groupSyncParam.setAdminName( groupSync.getAdminName() );
        }

        return groupSyncParam;
    }

    private static GroupSyncParam groupSyncToGroupSyncParamV1(GroupSyncV1 groupSyncV1) {
        if ( groupSyncV1 == null ) {
            return null;
        }

        GroupSyncParam groupSyncParam = new GroupSyncParam();
        groupSyncParam.setCode( groupSyncV1.getCode() );
        groupSyncParam.setName( groupSyncV1.getName() );
        groupSyncParam.setParentCode( groupSyncV1.getParentCode() );
        groupSyncParam.setRootFlag( groupSyncV1.getRoot() );
        if (StringUtils.isNotBlank(groupSyncV1.getAdminName())) {
            groupSyncParam.setAdminName( groupSyncV1.getAdminName() );
        }

        return groupSyncParam;
    }

    public static List<GroupSyncParam> grpcsToSyncGroups(List<GroupSync> grpcs) {
        if ( grpcs == null ) {
            return Collections.emptyList();
        }

        List<GroupSyncParam> list = new ArrayList<>( grpcs.size() );
        for ( GroupSync groupSync : grpcs ) {
            list.add( groupSyncToGroupSyncParam( groupSync ) );
        }

        return list;
    }

    public static List<GroupSyncParam> grpcsToSyncGroupsV1(List<GroupSyncV1> grpcs) {
        if ( grpcs == null ) {
            return Collections.emptyList();
        }

        List<GroupSyncParam> list = new ArrayList<>( grpcs.size() );
        for ( GroupSyncV1 groupSyncV1 : grpcs ) {
            list.add( groupSyncToGroupSyncParamV1( groupSyncV1 ) );
        }

        return list;
    }
}
